#include "app_program.h"
#include "esp8266_driver.h"
#include "data_list.h"
#include "string.h"
#include "stdio.h"
#include <stdlib.h> 
#include "app_encryption.h"
#include "cJSON.h"
#include "app.h"
#include "http.h"
#include "dynamic_string_queue.h"

//定时器计数
#define DAY_SEC 86400
#define SYN_CHECK_TASK 600

static uint32_t seccount = 0;

static DataList sensor_list;
static CmdList cmd_list;

static char cmd[32] = {0};
static char data[64] = {0};

// 创建容量为5的队列
DynamicStringQueue *queue = NULL; 
//状态功能值
static SystemState current_state = DO_STATE_IDLE;

void business_initialization(void)
{
    init_data_list(&sensor_list);
    init_cmd_list(&cmd_list);
    queue = createQueue(10);
    if (!queue) {
        // printf("创建队列失败\n");
        return ;
    }
}

void send_to_sensor(void *con_cmd, uint16_t cmd_len)
{
    // 构建完整AT指令
    if (cmd_len > 255) {
        // printf("[错误] 指令长度 %d 超过限制\n", cmd_len);
        return;
    }
    
    char at_cmd[255];
    
    memcpy(at_cmd, con_cmd, cmd_len);
    // 验证指令长度（ESP8266 AT限制通常为256字节）

    ESP8266_SendCommand(at_cmd, "data:", 1000);
}

/**
 * @brief 提取并打印所有+CIPSTATUS:行
 * @param response 原始AT命令响应数据
 */
void add_to_com_queue(const char* response) {
    const char* line = response;
    while ((line = strstr(line, "+CIPSTATUS:")) != NULL) {
        // 找到行尾（\r\n或\n）
        const char* end = strchr(line, '\n');
        if (!end) end = line + strlen(line); // 防止没有换行符的情况
        
        // 计算本行长度
        int line_len = end - line;
        
        // 打印整行（原样输出）
        // printf("%.*s\n", line_len, line);
        add_cmd_record(&cmd_list, line);
        // 移动到下一行
        line = end + 1;
    }
}

/* 处理IPD数据 */
static void handle_ipd_data(uint8_t* cmd_msg)
{
    uint8_t *start = cmd_msg;
    uint8_t *end = NULL;
    char cmd_str[256] = {0};
    do{
        start = (uint8_t *)strstr((const char *)start, "+IPD,");
							// printf("start%s\n", start);
        if(start == NULL)
				{
					return;
				}      
        start += 5;
			// printf("%c\n", start[0]);

    }while (start[0] == '4');
    
    start -= 5;
    end = (uint8_t *)strstr((const char *)start, "\r\n");
    end[0] = '\0';
    memcpy(cmd_str, start, end - start);
    // printf("cmd_str:[%s]\n", cmd_str);
    // if(start != NULL && tmp[0] != '4')
    // {
    //     char *end = strstr(start, "\r\n");
    //     memcpy(cmd_str, start, end - start);
    //     // printf("cmd_str:%s\n", cmd_str);
    // }

    /* 去掉回车换行 */
    //cmd_str[strlen(cmd_str) - 2] = '\0';
    
    /* 提取数据部分 */
    uint8_t *data_ptr = (uint8_t *)strstr(cmd_str, ":");
    if (data_ptr == NULL) return;
    data_ptr++;  // 跳过冒号

    // printf("Received IPD data: %s\n", data_ptr);
    
    /* 解密数据 */
    uint8_t decrypted[128] = {0};

    base64_to_decrypt((const char *)data_ptr, AES_CBC_MODE, decrypted, sizeof(decrypted));
    
    // // printf("data_ptr:%s\n", decrypted);
    /* 处理有效数据 */
    if (strstr((const char *)decrypted, "data:") != NULL) {
        memcpy(data_ptr, decrypted, strlen((const char *)decrypted) + 1);
        add_cmd_record(&cmd_list, cmd_str);
        // printf("Processed command: %s\n", cmd_str);
    }
}

/* 处理状态查询 */
static void handle_status_query(uint8_t* cmd_msg)
{
    add_to_com_queue((const char *)cmd_msg);
}

void parse_device_status(const char *json_str) {
    // 解析JSON字符串
    cJSON *json = cJSON_Parse(json_str);
    if (!json) {
        printf("JSON解析失败: %s\n", cJSON_GetErrorPtr());
        return;
    }

    // 检查是否是对象类型
    if (!cJSON_IsObject(json)) {
        printf("错误: 不是有效的JSON对象\n");
        cJSON_Delete(json);
        return;
    }

    // 获取各个字段
    cJSON *ipd = cJSON_GetObjectItemCaseSensitive(json, "ipd");
    cJSON *status = cJSON_GetObjectItemCaseSensitive(json, "status");
    cJSON *deviceType = cJSON_GetObjectItemCaseSensitive(json, "deviceType");

    // 验证字段是否存在和类型正确
    if (!cJSON_IsString(ipd) || !cJSON_IsString(status) || !cJSON_IsString(deviceType)) {
        // printf("错误: JSON字段类型不正确\n");
        cJSON_Delete(json);
        return;
    }

    // 打印解析结果
    printf("设备IPD: %s\n", ipd->valuestring);
    printf("设备状态: %s\n", status->valuestring);
    printf("设备类型: %s\n", deviceType->valuestring);
    printf("\n");

    //发送给TCP客户端控制状态
    uint16_t len =  strlen(json_str);
    memcpy(data, json_str, len);
    // printf("cmd:%s\n", cmd);
    // printf("data:%s\n", json_str);

    // 设置发送长度和连接ID
    sprintf(cmd, "AT+CIPSEND=%c,%d", ipd->valuestring[0], len); 

    // 释放内存
    cJSON_Delete(json);
}


/* 处理HTTP响应 */
void handle_http_response(uint8_t* cmd_msg)
{
    HttpResponse response = {0};
    
    /* 准备响应数据 */
    uart_rx_length = strlen((const char *)cmd_msg);
    memcpy(uart_rx_buffer, cmd_msg, uart_rx_length);
    
    /* 解析HTTP响应 */
    if (!http_response_receive(&response)) {
        return;
    }
    // printf("response.body = %s\n", response.body);
    /* 解密响应体 */
    uint8_t decrypted[512] = {0};
    // base64_to_decrypt(response.body, AES_CBC_MODE, decrypted, sizeof(decrypted));
    /* 解析JSON */
    cJSON *json = cJSON_Parse(response.body);
    if (!json) {
        printf("json error\n");
        http_response_free(&response);
        return;
    }

    // 解析对象中的各个字段
    cJSON *encryptedData = cJSON_GetObjectItemCaseSensitive(json, "encryptedData");
    if (cJSON_IsString(encryptedData) && (encryptedData->valuestring != NULL)) {
        // printf("The most total: %s\n", encryptedData->valuestring);
    }
    char *pload_str = cJSON_PrintUnformatted(encryptedData);
    if (!pload_str) {
        fprintf(stderr, "Error: Serialization failed\n");
        cJSON_Delete(json);
        return;
    }

    // printf("The most total:%s\n", pload_str);
    
    char *tmp = strstr(pload_str, "\"");
    tmp+=1;
    char *tmp2 = strstr(tmp, "\"");
    tmp[tmp2 - tmp] = '\0';
    // // printf("tmp%s", tmp);
    base64_to_decrypt(tmp, AES_CBC_MODE, decrypted, sizeof(decrypted));
    

    // printf("==== 解析有数据的JSON ====\n");
    parse_device_status((const char *)decrypted);

    free(pload_str);
    /* 清理资源 */
    cJSON_Delete(json);
    http_response_free(&response);
    // printf("---33----\n");
}

void recv_from_sensor(void)
{
    // char cmd_msg[256] = {0}; 
    
    ESP8266_ProcessReceivedData(NULL);
    // printf("cmd_msg:%s\n", cmd_msg); 
}


/* 解析传感器数据字符串 */
void parse_sensor_data(const char* data_str, SensorData* sensor_data) {
    // 假设数据格式为: "devicename=1,temp=25.5,humid=60.2,id=1001,ts=123456789,gdata=1"
    float temp = 0, humid = 0;
    int id = 0;
    int device = 0;
    int device_state = 0;
    unsigned long ts = 0;
    
    sscanf(data_str, "devicename=%d,temp=%f,humid=%f,id=%d,ts=%lu,gdata=%d", 
           &device,&temp, &humid, &id, &ts, &device_state);
    sensor_data->sensorname = device; //获取设备名字
    sensor_data->temperature = temp;
    sensor_data->humidity = humid;
    sensor_data->sensorid = id;
    sensor_data->timestamp = ts;
    sensor_data->gdata.data = device_state;
    switch (device)
    {
    case 1:
        sensor_data->device_type = TEMP_AND_HUM;
        break;
    case 2:
        sensor_data->device_type = CURTAIN; 
        break;
    case 3:
        sensor_data->device_type = LIGHT;
        break;
    
    default:
        break;
    }
}

// +IPD,0,88,"192.168.137.1",54569:data:temp=25.5,humid=60.2,id=1001,ts=1234567231423
/* 处理温湿度传感器数据  */
int process_esp_data(DataList* data_list, CmdList* cmd_list, const char* esp_recv) {
    if (!esp_recv || !strstr(esp_recv, "+IPD")) {
        return -1; // 无效数据格式
    }
    // 4. 解析传感器数据
    SensorData sensor_data;
    
    // // printf("-------------------------\n");
    // 1. 查找关键分隔符
    char* ip_start = strchr(esp_recv, ',');
    ip_start += 1;
    
    // 获取ipd
    sensor_data.ipd[0] = ip_start[0];
    sensor_data.ipd[1] = '\0';
    ip_start = strchr(ip_start, ',');
    ip_start += 1;
    ip_start = strchr(ip_start, ',');
    // printf("ip_start%s\n", ip_start);
    const char* ip_end = ip_start ? strchr(ip_start + 1, ',') : NULL;
    const char* data_start = strchr(esp_recv, ':');
    
    if (!ip_start || !ip_end || !data_start) {
        return -1; // 格式错误
    }
    
    // printf("---------22----------------\n");
    // 提取IP地址
    char ip[16] = {0};
    size_t ip_len = ip_end - (ip_start + 1);
    if (ip_len >= sizeof(ip)) {
        return -1; // IP地址过长
    }
    // printf("---------33----------------\n");
    strncpy(ip, ip_start + 1, ip_len);
    ip[ip_len] = '\0';
    // printf("ip = %s\n", ip);

    // 提取数据部分
    data_start = strstr(data_start, "data:");
    if (!data_start) {
        return -1; // 不包含有效数据
    }
    data_start += 5; // 跳过"data:"

    parse_sensor_data(data_start, &sensor_data);

    // 添加到数据链表
    if (add_data_record(data_list, ip, &sensor_data) != 0) {
        return -1; // 添加失败
    }

    // 直接删除当前处理的命令（而不是遍历整个链表）
    // 注意：这里假设esp_recv就是cmd_list中的某个节点的command
    delete_cmd_record(cmd_list, esp_recv);

    return 0;
}

/**
 * @brief STATE_IDLE 状态处理 - 定时采集传感器数据
 * @param interval_ms 采集间隔(毫秒)
 * @return 0:成功 1:设备未连接 2:采集超时
 */
uint8_t Handle_Idle_State() {
      // 处理所有包含"data:"的命令
    CmdNode* current = cmd_list.head;
    while (current != NULL) {
        if (strstr(current->command, "data:")) {
            // printf(" current->command%s\n", current->command);
            process_esp_data(&sensor_list, &cmd_list, current->command);
        }else if(strstr(current->command, "+CIPSTATUS:")){ //规则待定
            // printf(" current->command%s\n", current->command);
            Parse_TCP_State(current->command);
            delete_cmd_record(&cmd_list, current->command);
        }
        current = current->next;
    }
		return 0;
}

// 假设的 sendHttp 函数原型声明  
int8_t Send_Http(const char* ip, const SensorData* data)
{
    // printf("device_type%d\n", data->device_type);
    /* 作包 */
    // 创建根对象
    cJSON *root = cJSON_CreateObject();
    if (!root) {
        fprintf(stderr, "Error: Failed to create root object\n");
        return -1;
    }
    char *json_str = NULL;
    
    cJSON_AddStringToObject(root, "ipd", data->ipd);
    char ipd[64] = {0};
    switch (data->device_type)
    {
        case TEMP_AND_HUM: //温湿度组包发送
        sprintf(ipd, "sensor_%c", data->ipd[0]);
        cJSON_AddStringToObject(root, "deviceid", ipd);
        cJSON_AddStringToObject(root, "devicename", "温湿度传感器");
        cJSON_AddNumberToObject(root, "temperature", data->temperature);
        cJSON_AddNumberToObject(root, "humidity", data->humidity);
        
        break;
        case CURTAIN:       //窗帘发送
        sprintf(ipd, "curtain_%c", data->ipd[0]);
        cJSON_AddStringToObject(root, "deviceid", ipd);
        cJSON_AddStringToObject(root, "devicename", "客厅窗帘");
        cJSON_AddNumberToObject(root, "curtain", data->gdata.curtain);
        
        break;
        
        case LIGHT:         //灯的状态
        sprintf(ipd, "light_%c", data->ipd[0]);
        cJSON_AddStringToObject(root, "deviceid", ipd);
        cJSON_AddStringToObject(root, "devicename", "客厅主灯");
        cJSON_AddNumberToObject(root, "lights", data->gdata.light);
        
        break;
        
        default:
        break;
    }
    
    // 3. 序列化并打印
    json_str = cJSON_PrintUnformatted(root);
    if (!json_str) {
        fprintf(stderr, "Error: Serialization failed\n");
        cJSON_Delete(root);
        return -1;
    }
    // printf("json_str = %p\n", json_str);
    // printf("Successfully serialized JSON:\n%s\n", json_str);
    if (!json_str) {
        fprintf(stderr, "Error: Serialization failed\n");
        cJSON_Delete(root);
        return -1;
    }
    
    size_t orig_len = strlen(json_str);  
  
    char* result;
 
    encrypt_to_base64((const uint8_t *)json_str, orig_len, AES_CBC_MODE, &result);

    // printf("Encoded: %s\n", result);

    cJSON *pload = cJSON_CreateObject();
    if (!pload) {
        fprintf(stderr, "Error: Failed to create root object\n");
        return -1;
    }
    cJSON_AddStringToObject(pload, "encryptedData", result);
    cJSON_AddStringToObject(pload, "encryptionMode", "cbc");
    char *pload_str = cJSON_PrintUnformatted(pload);
    if (!pload_str) {
        fprintf(stderr, "Error: Serialization failed\n");
        free(json_str);
        cJSON_Delete(root);
        cJSON_Delete(pload);
        return -1;
    }

    // printf("The most total:%s\n", pload_str);

     // 发送POST请求
     HttpRequest request = {
        .type = HTTP_POST,
        .host = IP_ADDR,
        .path = ADDR_PATH_DEVICE_DATA,
        .json_body = pload_str,
        .port = PORT
    };
    // printf("到底打印了几次11\n");
    http_request_send(&request);

    cJSON_Delete(pload);
    free(pload_str);

    free(json_str);
    cJSON_Delete(root); 
    //发送数据
    // send_encrypted_data(result);
    free(result);
    // free(result2);
    return 0;
}

/**
 * @brief STATE_UPLOAD 状态处理 - 定时上传数据
 * @return 成功上传的设备数量
 */
uint8_t Handle_Upload_State() {
    uint8_t successCount = 0;
    DataNode *current = sensor_list.head;
    DataNode *prev = NULL;
    DataNode *to_delete = NULL;
    
    while (current != NULL) {
        // 检查是否达到上传间隔
        
        // 发送数据到云端
        int send_result = Send_Http(current->ip_address, &current->data);
        
        if (send_result == 0) { // 发送成功
            successCount++;
            to_delete = current;
            
            // 移动当前指针到下一个节点
            if (prev == NULL) {
                // 删除头节点
                sensor_list.head = current->next;
                current = sensor_list.head;
            } else {
                // 删除中间或尾节点
                prev->next = current->next;
                current = prev->next;
            }
            
            // 释放内存
            free(to_delete);
            to_delete = NULL;
        } else {
            // 发送失败，继续下一个节点
            prev = current;
            current = current->next;
            
            // 可以添加重试机制或错误处理
            #ifdef ENABLE_RETRY
            if (send_result == -1) { // 网络错误
                // 记录错误日志或触发重连机制
            }
            #endif
        }
    }
    
    return successCount;
}

/**
 * @brief DO_DEVIVE_CONTROL 设备状态请求求控制
 * @return 非法IP数量
 */
bool Handle_device_control(void){
    HttpRequest request = {
        .type = HTTP_GET,
        .host = IP_ADDR,
        .path = ADDR_PATH_DEVICE_CHANGE,
        .json_body = NULL,
        .port = PORT
    };
   return http_request_send(&request);
}
void send_to_device()
{
    if(cmd[0] != 0 && data[0] != 0)
    {
        printf("data:%s len: len%d\n", data, strlen(data));
        printf("cmd:%s\n", cmd);
        if(ESP8266_SendCommand(cmd, ">", 1000)) {
            // 发送实际数据
            HAL_Delay(200);
            // printf("json_str:%s\n", json_str);
            // ESP8266_SendData(json_str, len);
            printf("-----\n");
            ESP_Status ret = ESP8266_SendData(data, strlen(data));
            printf("ret =%d\n", ret);
        }
        memset(cmd, 0x00, sizeof(cmd));
        memset(data, 0x00, sizeof(data));
    }
        // ESP8266_SendData("AT+CIPSEND=0,5\r\n", 16);
        // // 发送实际数据
        // HAL_Delay(200);
        // ESP_Status ret = ESP8266_SendData("hello", 5);
        // printf("ret =%d\n", ret);
    
}
void Handle_recv_data(void)
{
    char *cmd_msg;
    while (dequeue(queue, &cmd_msg)) {    
        // printf("cmd_msg:\n\n%s\n\n", cmd_msg);
        if(strstr(cmd_msg, "\r\n") != NULL)
        {
            handle_http_response((uint8_t *)cmd_msg);
        }
        if(strstr(cmd_msg, "IPD") != NULL)
        {
            handle_ipd_data((uint8_t *)cmd_msg);
        }
        else if(strstr(cmd_msg, "+CIPSTATUS:") != NULL)
        {
            handle_status_query((uint8_t *)cmd_msg);
        }
        free(cmd_msg);
        cmd_msg = NULL;
    }
}

void System_State_Machine() {
    switch (current_state) {

        case DO_STATE_IDLE:     /* 空闲任务，用来处理传感器的数据或回应 */
            Handle_Idle_State();
            current_state = DO_STATE_UPLOAD;
        break;
        
        case DO_STATE_UPLOAD:   /* 上传服务器数据 */
            Handle_Upload_State();
            current_state = DO_STATE_SYN_CHECK;
        break;
        
        case DO_STATE_SYN_CHECK: /* SYN 阈值检查 */
            Handle_SYN_Check_State();
            current_state = DO_STATE_KEY_ROTATE;
        break;
        
        case DO_STATE_KEY_ROTATE: /* 24小时更新密钥 */
            if(seccount == (DAY_SEC-1))
            {
                Handle_Key_Rotate_State();
            }
            current_state = DO_DEVIVE_CON_STATE;
        break;
        
        case DO_DEVIVE_CON_STATE: /* 设备控制状态获取 */
            if(seccount % 3 == 0)
            {
                Handle_device_control();
            } 
            current_state = DO_DATA_HANDLE;
        break;

        case DO_DATA_HANDLE:     /* 设备控制状态获取 */
            Handle_recv_data();
            current_state = DO_DEVIVE_CONTROL;
        break;
        
        case DO_DEVIVE_CONTROL:   /* 设备控制 */
            if(seccount % 3 == 0)
            {
                send_to_device();
            } 
            current_state = DO_STATE_IDLE;
        break;
        default:
        break;
    }
}


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    seccount++;
    
    if(seccount % SYN_CHECK_TASK == 0){    /* 每10分钟进行一次 */
        /* 定时进行SYN检查 */
        ESP8266_SendCommand("AT+CIPSTATUS", "OK", 10000); // 查询TCP连接的状态
    }
}
